/////////////////////////////////////////////////////////////////////////////
// This file is part of the "Java-DAP" project, a Java implementation
// of the OPeNDAP Data Access Protocol.
//
// Copyright (c) 2007 OPeNDAP, Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
/////////////////////////////////////////////////////////////////////////////
using System;
using NDODS.DAP.BaseTypes;
using NDODS.DAP.Exceptions;

namespace NDODS.DAP.Primitives
{
	
	/// <summary> A vector of doubles.
	/// 
	/// </summary>
	/// <author>  ndp
	/// </author>
	/// <version>  $Revision: 15901 $
	/// </version>
	/// <seealso cref="PrimitiveVector">
	/// </seealso>
	[Serializable]
	public class Float32PrimitiveVector:PrimitiveVector, System.ICloneable
	{
		//UPGRADE_NOTE: Respective javadoc comments were merged.  It should be changed in order to comply with .NET documentation conventions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1199'"
		/// <summary> Returns the number of elements in the array.
		/// 
		/// </summary>
		/// <returns> the number of elements in the array.
		/// </returns>
		/// <summary> Sets the number of elements in the array.  Allocates a new primitive
		/// array of the desired size.  Note that if this is called multiple times,
		/// the old array and its contents will be lost.
		/// <p/>
		/// Only called inside of <code>Deserialize</code> method or in derived
		/// classes on server.
		/// 
		/// </summary>
		/// <param name="len">the number of elements in the array.
		/// </param>
		override public int Length
		{
			get
			{
				return vals.Length;
			}
			
			set
			{
				vals = new float[value];
			}
			
		}
		//UPGRADE_NOTE: Respective javadoc comments were merged.  It should be changed in order to comply with .NET documentation conventions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1199'"
		/// <summary> Returns (a reference to) the internal storage for this PrimitiveVector
		/// object.
		/// <h2>WARNING:</h2>
		/// Because this method breaks encapsulation rules the user must beware!
		/// If we (the OPeNDAP prgramming team) choose to change the internal
		/// representation(s) of these types your code will probably break.
		/// <p/>
		/// This method is provided as an optimization to eliminate massive
		/// copying of data.
		/// 
		/// </summary>
		/// <returns> The internal array of floats.
		/// </returns>
		/// <summary> Set the internal storage for PrimitiveVector.
		/// <h2><i>WARNING:</i></h2>
		/// Because this method breaks encapsulation rules the user must beware!
		/// If we (the OPeNDAP prgramming team) choose to change the internal
		/// representation(s) of these types your code will probably break.
		/// <p/>
		/// This method is provided as an optimization to eliminate massive
		/// copying of data.
		/// </summary>
		override public System.Object InternalStorage
		{
			get
			{
				return (vals);
			}
			
			set
			{
				vals = (float[]) value;
			}
			
		}
		
		new internal const long serialVersionUID = 1;
		
		/// <summary> the array of <code>float</code> values.</summary>
		private float[] vals;
		
		/// <summary> Constructs a new <code>Float32PrimitiveVector</code>.
		/// 
		/// </summary>
		/// <param name="var">the template <code>BaseType</code> to use.
		/// </param>
		public Float32PrimitiveVector(BaseType var):base(var)
		{
		}
		
		/// <summary> Returns a clone of this <code>Float32PrimitiveVector</code>.  A deep
		/// copy is performed on all data inside the variable.
		/// 
		/// </summary>
		/// <returns> a clone of this <code>Float32PrimitiveVector</code>.
		/// </returns>
		public override System.Object Clone()
		{
			Float32PrimitiveVector v = (Float32PrimitiveVector) base.Clone();
			if (vals != null)
			{
				v.vals = new float[vals.Length];
				Array.Copy(vals, 0, v.vals, 0, vals.Length);
			}
			return v;
		}
		
		/// <summary> Return the i'th value as a <code>double</code>.
		/// 
		/// </summary>
		/// <param name="i">the index of the value to return.
		/// </param>
		/// <returns> the i'th value.
		/// </returns>
		public float getValue(int i)
		{
			return vals[i];
		}
		
		/// <summary> Set the i'th value of the array.
		/// 
		/// </summary>
		/// <param name="i">     the index of the value to set.
		/// </param>
		/// <param name="newVal">the new value.
		/// </param>
		public void  setValue(int i, float newVal)
		{
			vals[i] = newVal;
		}
		
		/// <summary> Prints the value of all variables in this vector.  This
		/// method is primarily intended for debugging OPeNDAP applications and
		/// text-based clients such as geturl.
		/// 
		/// </summary>
		/// <param name="os">   the <code>StreamWriter</code> on which to Print the value.
		/// </param>
		/// <param name="space">this value is passed to the <code>PrintDeclaration</code> method,
		/// and controls the leading spaces of the output.
		/// </param>
		/// <seealso cref="BaseType.printVal(StreamWriter, String, bool)">
		/// </seealso>
		public override void  printVal(System.IO.StreamWriter os, System.String space)
		{
			int len = vals.Length;
			for (int i = 0; i < len - 1; i++)
			{
				os.Write(vals[i]);
				os.Write(", ");
			}
			// Print last value, if any, without trailing comma
			if (len > 0)
				os.Write(vals[len - 1]);
		}
		
		/// <summary> Prints the value of a single variable in this vector.
		/// method is used by <code>DArray</code>'s <code>PrintValue</code> method.
		/// 
		/// </summary>
		/// <param name="os">   the <code>StreamWriter</code> on which to Print the value.
		/// </param>
		/// <param name="index">the index of the variable to Print.
		/// </param>
		/// <seealso cref="DArray.printVal(StreamWriter, String, bool)">
		/// </seealso>
		public override void  printSingleVal(System.IO.StreamWriter os, int index)
		{
			os.Write(vals[index]);
		}
		
		/// <summary> Reads data from a <code>DataInputStream</code>. This method is only used
		/// on the client side of the OPeNDAP client/server connection.
		/// 
		/// </summary>
		/// <param name="source">  a <code>DataInputStream</code> to Read from.
		/// </param>
		/// <param name="sv">      The <code>ServerVersion</code> returned by the server.
		/// (used by <code>DSequence</code> to determine which protocol version was
		/// used).
		/// </param>
		/// <param name="statusUI">The <code>StatusUI</code> object to use for GUI updates
		/// and user cancellation notification (may be null).
		/// </param>
		/// <throws>  DataReadException when invalid data is Read, or if the user </throws>
		/// <summary>                           cancels the download.
		/// </summary>
		/// <throws>  EOFException      if EOF is found before the variable is completely </throws>
		/// <summary>                           deserialized.
		/// </summary>
		/// <throws>  IOException       thrown on any other InputStream exception. </throws>
		/// <seealso cref="ClientIO.deserialize(DataInputStream, ServerVersion, StatusUI)">
		/// </seealso>
		//UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'"
		//UPGRADE_NOTE: Synchronized keyword was removed from method 'Deserialize'. Lock expression was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1027'"
		public override void  Deserialize(System.IO.BinaryReader source, ServerVersion sv, IStatusUI statusUI)
		{
			lock (this)
			{
				for (int i = 0; i < vals.Length; i++)
				{
					vals[i] = source.ReadSingle();
					if (statusUI != null)
					{
						statusUI.IncrementByteCount(8);
						if (statusUI.UserCancelled())
							throw new DataReadException("User cancelled");
					}
				}
			}
		}
		
		/// <summary> Writes data to a <code>DataOutputStream</code>. This method is used
		/// primarily by GUI clients which need to download OPeNDAP data, manipulate
		/// it, and then re-save it as a binary file.
		/// 
		/// </summary>
		/// <param name="sink">a <code>DataOutputStream</code> to write to.
		/// </param>
		/// <throws>  IOException thrown on any <code>OutputStream</code> </throws>
		/// <summary>                     exception.
		/// </summary>
		//UPGRADE_TODO: Class 'java.io.DataOutputStream' was converted to 'System.IO.BinaryWriter' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataOutputStream'"
		public override void  Externalize(System.IO.BinaryWriter sink)
		{
			for (int i = 0; i < vals.Length; i++)
			{
				sink.Write(vals[i]);
			}
		}
		
		/// <summary> Write a subset of the data to a <code>DataOutputStream</code>.
		/// 
		/// </summary>
		/// <param name="sink">   a <code>DataOutputStream</code> to write to.
		/// </param>
		/// <param name="start"> starting index (i=start)
		/// </param>
		/// <param name="stop">  ending index (i<=stop)
		/// </param>
		/// <param name="stride">index stride (i+=stride)
		/// </param>
		/// <throws>  IOException thrown on any <code>OutputStream</code> exception. </throws>
		//UPGRADE_TODO: Class 'java.io.DataOutputStream' was converted to 'System.IO.BinaryWriter' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataOutputStream'"
		public virtual void  externalize(System.IO.BinaryWriter sink, int start, int stop, int stride)
		{
			for (int i = start; i <= stop; i += stride)
				sink.Write(vals[i]);
		}
		
		/// <summary> Create a new primitive vector using a subset of the data.
		/// 
		/// </summary>
		/// <param name="start"> starting index (i=start)
		/// </param>
		/// <param name="stop">  ending index (i<=stop)
		/// </param>
		/// <param name="stride">index stride (i+=stride)
		/// </param>
		/// <returns> new primitive vector, of type Float32PrimitiveVector.
		/// </returns>
		public override PrimitiveVector subset(int start, int stop, int stride)
		{
			Float32PrimitiveVector n = new Float32PrimitiveVector(Template);
			stride = System.Math.Max(stride, 1);
			stop = System.Math.Max(start, stop);
			int length = 1 + (stop - start) / stride;
			n.Length = length;
			
			int count = 0;
			for (int i = start; i <= stop; i += stride)
			{
				n.setValue(count, vals[i]);
				count++;
			}
			return n;
		}
	}
}